package com.naruto.thinkmgr.comm;

import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 全局异常处理。Controller中抛出的异常由此类来处理
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    private MappingJackson2JsonView jsonView = new MappingJackson2JsonView();

    @ExceptionHandler(Exception.class)
    public ModelAndView defaultExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e) {
        logger.warn("global exception handle", e);
        String message = "服务器内部错误";
        ModelAndView mav = new ModelAndView();
        //页面返回和JSON返回的数据有点不一样。页面需要展示更详细的信息，JSON要跟其他接口统一，方便前端处理。
        Map<String, Object> model = new HashMap<>();
        if (e instanceof UnauthorizedException) {
            mav.setStatus(HttpStatus.FORBIDDEN);
            message = "无权访问";
        }
        if (isAjax(req)) {
            mav.setView(jsonView);
            mav.setStatus(HttpStatus.OK);
            model.put("code", Constants.ApiResultCode.FAIL);
        } else {
            mav.setViewName("error");
            model.put("status", mav.getStatus().value());
            model.put("path", req.getRequestURI());
            model.put("error", mav.getStatus().toString());
            mav.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        model.put("message", message);
        mav.addAllObjects(model);
        return mav;
    }

    private boolean isAjax(HttpServletRequest req) {
        return req.getHeader("x-requested-with") != null;
    }
}
